# @FileName  : main.py
# @Time      : 2024/7/4 17:18
# @Author    : LuZhaoHui
# @Software  : PyCharm

import time

from conf import *
from msql import *
from ocrUI import Ui_MainWindow
from tcp import *
from webClient import *


# class MyServer(socketserver.StreamRequestHandler):
#     def handle(self):
#         # print self.request,self.client_address,self.server
#         global CurOcrProcList
#         conn = self.request
#         print(self.client_address)
#         while True:
#             # 接收信息
#             data = conn.recv(1024)
#             # 处理命令:@@{info}@@
#             err = 1
#             if data[:2] == '@@' and data[-2:] == '@@':
#                 err = 0
#                 CurOcrProcList.append(data[2:-2])
#             conn.sendall('@@{err:%d}@@' % (err))
#         print(" tcp server exit")


class ocrRun(QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None):
        super(ocrRun, self).__init__(parent)
        self.setupUi(self)
        self.initRedirection()
        self.config = ocrConf('ocr.ini')
        self.initVar()
        self.init()
        self.initUI()

    def initRedirection(self):
        self.stdoutbak = sys.stdout
        self.stderrbak = sys.stderr

    def resetRedirection(self):
        sys.stdout = self.stdoutbak
        sys.stderr = self.stderrbak

    def closeEvent(self, event):
        if not self.start and showBoxYes(self, "系统将退出，是否确认?  "):
            self.exit()
            event.accept()
        else:
            event.ignore()

    def exit(self):
        if self.tcpServer != None:
            self.tcpClose()
        if self.dataSsh != None:
            del self.dataSsh
        if self.msql != None:
            del self.msql
        self.resetRedirection()

    def initVar(self):
        # 图片路径
        self.ocrPath = self.config.varConf['OcrPath']
        # 识别配置
        self.ocrConfRightToLeft = self.config.varConf['OcrConfRightToLeft']
        self.ocrConfUpToDown = self.config.varConf['OcrConfUpToDown']
        self.ocrConfUpToDownWordNums = self.config.varConf['OcrConfUpToDownWordNums']
        self.ocrConfFantiToJianti = self.config.varConf['OcrConfFantiToJianti']
        self.ocrConfWordSpaceChar = self.config.varConf['OcrConfWordSpaceChar']
        self.OcrConfPeriodTime = self.config.varConf['OcrConfPeriodTime']
        # 控制，数据接口
        self.isTcpServer = self.config.varConf['IsTcpServer']
        self.tcpHost = self.config.varConf['TcpHost']
        self.tcpPort = self.config.varConf['TcpPort']
        self.isOcrWeb = self.config.varConf['IsOcrWeb']
        self.OcrType = self.config.varConf['OcrType']
        self.ocrWebHost = self.config.varConf['OcrWebHost']
        self.ocrWebPort = self.config.varConf['OcrWebPort']
        self.OcrFileMaxByte = self.config.varConf['OcrFileMaxByte']
        self.API_KEY = self.config.varConf['API_KEY']
        self.SECRET_KEY = self.config.varConf['SECRET_KEY']
        self.isDb = self.config.varConf['IsDb']
        self.dbHost = self.config.varConf['DbHost']
        self.dbPort = self.config.varConf['DbPort']
        self.dbUser = self.config.varConf['DbUser']
        self.dbPass = self.config.varConf['DbPass']
        self.dbName = self.config.varConf['DbName']
        self.isData = self.config.varConf['IsData']
        self.dataHost = self.config.varConf['DataHost']
        self.dataPort = self.config.varConf['DataPort']
        self.dataUser = self.config.varConf['DataUser']
        self.dataPass = self.config.varConf['DataPass']
        self.dataPath = self.config.varConf['DataPath']
        self.msql = None
        if self.isDb:
            self.msql = mysqlProc(self.dbHost, self.dbPort, self.dbUser, self.dbPass, self.dbName)
        self.tcpServer = None
        self.tcpSocket = None
        if self.isTcpServer:
            self.tcpStart()
        self.dataSsh = None
        if self.isData:
            self.dataSsh = sshClient(self.ocrPath)
        self.curFilmTitle = ''
        self.curFilmNo = 0
        self.curOcrProcNums = 0
        self.curOcrFilmNums = 0
        self.ocrProcNums = 0
        self.dataThread = None
        self.procThread = None
        self.start = False

    def init(self):
        if self.config.varConf['WindowMax'] > 0:
            self.showMaximized()
        self.setWindowFlags(Qt.WindowCloseButtonHint | Qt.WindowMinimizeButtonHint)
        self.setWindowIcon(QIcon(LOGO))
        self.setWindowTitle(self.config.varConf['Title'])
        if self.config.varConf['WindowMin'] > 0:
            self.showMinimized()

        # 图片处理路径
        if os.path.isdir(self.ocrPath):
            self.lineEditScanDir.setText(self.ocrPath)
        else:
            self.ocrPath = ''
        # 识别配置
        self.checkBoxRightToLeft.setChecked(self.ocrConfRightToLeft)
        self.checkBoxUpToDown.setChecked(self.ocrConfUpToDown)
        self.spinBoxUpToDownWordNums.setValue(self.ocrConfUpToDownWordNums)
        self.checkBoxFantiToJianti.setChecked(self.ocrConfFantiToJianti)
        self.doubleSpinBoxDelaySeconds.setValue(self.OcrConfPeriodTime)
        self.comboBoxWordSpaceChar.setCurrentText(self.ocrConfWordSpaceChar)
        # 控制，数据接口
        self.checkBoxTcpServer.setChecked(self.isTcpServer)
        self.spinBoxTcpPort.setValue(self.tcpPort)
        self.checkBoxDatabase.setChecked(self.isDb)
        self.lineEditDatabaseInterface.setText('%s:%d@%s->%s' % (self.dbHost, self.dbPort, self.dbUser, self.dbName))
        # 远程数据
        self.checkBoxDataRemote.setChecked(self.isData)
        self.spinBoxDataPort.setValue(self.dataPort)
        self.lineEditDataPath.setText('%s:%d@%s->%s' % (self.dataHost, self.dataPort, self.dataUser, self.dataPath))

    def initUI(self):
        # 间隔字符
        setComboBoxHeight(self.comboBoxWordSpaceChar, 18)
        # 选择目录
        self.pushButtonDir.clicked.connect(self.choiceOcrPath)
        # 识别配置
        self.checkBoxRightToLeft.toggled.connect(self.rightToLeft)
        self.checkBoxUpToDown.toggled.connect(self.upToDown)
        self.checkBoxFantiToJianti.toggled.connect(self.fantiToJianti)
        self.spinBoxUpToDownWordNums.valueChanged.connect(self.upToDownWordNums)
        self.comboBoxWordSpaceChar.currentIndexChanged.connect(self.wordSpaceChar)
        self.doubleSpinBoxDelaySeconds.valueChanged.connect(self.delaySeconds)
        # 控制，数据接口
        self.checkBoxTcpServer.toggled.connect(self.enableTcpServer)
        self.spinBoxTcpPort.valueChanged.connect(self.confTcpPort)
        self.checkBoxDatabase.toggled.connect(self.enableDatabase)
        self.checkBoxDataRemote.toggled.connect(self.enableDataRemote)
        # 识别服务启动
        self.pushButtonOcrProc.clicked.connect(self.ocrProc)
        self.flushOcrNums()
        if self.OcrType == 1:
            self.labelOcrType.setText("百度在线")
        elif self.OcrType == 2:
            self.labelOcrType.setText("百度离线")
        if self.config.varConf['Start'] > 0:
            self.ocrProc()

    def flushUI(self, enable):
        self.lineEditFilmTitle.setReadOnly(not enable)
        self.spinBoxFilmNo.setReadOnly(not enable)
        self.pushButtonDir.setEnabled(enable)
        self.checkBoxRightToLeft.setEnabled(enable)
        self.checkBoxUpToDown.setEnabled(enable)
        self.spinBoxUpToDownWordNums.setReadOnly(not enable)
        self.checkBoxFantiToJianti.setEnabled(enable)
        self.comboBoxWordSpaceChar.setEnabled(enable)
        self.doubleSpinBoxDelaySeconds.setReadOnly(not enable)
        self.checkBoxTcpServer.setEnabled(enable)
        self.spinBoxTcpPort.setReadOnly(not enable)
        self.checkBoxDatabase.setEnabled(enable)
        self.checkBoxDataRemote.setEnabled(enable)
        self.spinBoxDataPort.setReadOnly(not enable)

    def tcpStart(self):
        # 创建服务器对象
        self.tcpServer = QTcpServer()
        self.tcpServer.listen(QHostAddress(self.tcpHost), self.tcpPort)
        self.tcpServer.newConnection.connect(self.tcpNewConnection)

    # 新连接
    def tcpNewConnection(self):
        if self.tcpSocket is not None:
            # 已经连接-关闭
            self.tcpSocket.disconnectFromHost()
        # 处理新连接
        self.tcpSocket = self.tcpServer.nextPendingConnection()
        self.tcpSocket.readyRead.connect(self.tcpRecvData)
        # 记录已连接的客户端
        client_address = self.tcpSocket.peerAddress().toString()
        client_port = self.tcpSocket.peerPort()
        print("tcp connect [%s:%d]" % (client_address, client_port))

    # 接收信息
    def tcpRecvData(self):
        data = self.tcpSocket.readAll().data().decode('utf-8')
        print(data)
        # 处理命令:@@{info}@@
        err = 1
        isHalt = False
        if data[:2] == '@@' and data[-2:] == '@@':
            err = 0
            if self.start:
                if data[2:-2] == '{heart}':
                    # 测试
                    msg = '@@{heart:%d}@@' % (self.curOcrProcNums)
                elif data[2:-2] == '{halt}':
                    msg = data
                    isHalt = True
                else:
                    # 数据
                    self.dataThread.addData(data[2:-2])
                    if self.isOcrWeb:
                        self.procThread.addProc(data[2:-2])
                    msg = '@@{err:%d}@@' % (err)
        self.tcpSocket.write(msg.encode('utf-8'))
        self.tcpSocket.disconnectFromHost()
        self.tcpSocket = None
        if isHalt and self.curOcrProcNums == 0:
            print("system halt")
            self.halt()

    # 关闭连接
    def tcpClose(self):
        # 关闭连接
        if self.tcpSocket is not None:
            self.tcpSocket.disconnectFromHost()
            self.tcpSocket = None
        # 关闭服务器
        if self.tcpServer is not None:
            self.tcpServer.close()
            self.tcpServer = None

    def flushOcrNums(self):
        self.labelNoProcNums.setText('%d' % (self.curOcrProcNums))
        self.labelFilmNums.setText('%d' % (self.curOcrFilmNums))
        self.labelProcNums.setText('%d' % (self.ocrProcNums))

    def halt(self):
        self.exit()
        sys.exit(1)

    # 识别服务启动
    def ocrProc(self):
        if self.start:
            # 启动->关闭
            self.pushButtonOcrProc.setText('识别服务启动')
            self.dataThread.dataStop()
            if self.isOcrWeb and self.procThread != None:
                self.procThread.procStop()
            if self.dataSsh != None:
                self.dataSsh.sshClose()
            self.flushUI(True)
        else:
            # 关闭->启动
            self.start = True
            if self.dataSsh != None:
                self.dataSsh.setConf(self.dataHost, self.dataPort, self.dataUser, self.dataPass, self.dataPath)
            self.dataThread = ocrDataThread(pathJoin(self.ocrPath, 'data.txt'))
            self.dataThread.update_item.connect(self.dataShow)
            self.dataThread.start()
            if self.isOcrWeb:
                if self.OcrType == 1:
                    paraStr = '%s,%s,%d' % (self.API_KEY, self.SECRET_KEY, self.OcrFileMaxByte)
                else:
                    paraStr = '%s,%d,%d' % (self.ocrWebHost, self.ocrWebPort, self.OcrFileMaxByte)

                self.procThread = ocrProcThread(self.ocrPath,
                                                pathJoin(self.ocrPath, 'proc.txt'),
                                                self.OcrType, paraStr)
                self.procThread.update_item.connect(self.procShow)
                self.procThread.start()
            self.pushButtonOcrProc.setText('识别服务关闭')
            # 打开
            self.flushUI(False)

    # 处理结果-
    def ocrProcJson(self, filmTitle, filmNo, jsonData):
        if jsonData == None:
            return
        name = jsonData[0]
        kb = jsonData[1]
        ocrJson = jsonData[2]
        ocrTxt1 = jsonData[3]
        ocrTxt2 = jsonData[4]
        ocrPy = jsonData[5]
        # ocrJson = jsonData['result'][2]
        # ocrTxt1 = jsonData['result'][3]
        # ocrTxt2 = jsonData['result'][4]
        # ocrPy = jsonData['result'][5]
        # name = jsonData['name']
        # kb = jsonData['KB']
        code = 0
        if self.msql != None:
            if self.ocrPath == name[:len(self.ocrPath)]:
                name = name[len(self.ocrPath):]
            # to DB
            code, ret = self.msql.addOcr(filmTitle,
                                         filmNo,
                                         name, kb,
                                         ocrJson, ocrTxt1, ocrTxt2, ocrPy)
            saveLog('[%s]-[%s]' % (name, ret), self.ocrPath, log='ocr.log')
            self.labelOcrProcResult.setText(ret if code == 0 else 'error')
        else:
            if len(ocrTxt1) > 0:
                txtName = name[:-3] + 'txt'
                # to txt
                with open(txtName, 'w', encoding='utf-8') as f:
                    f.write(ocrTxt1 + '\n')
                    f.write(ocrTxt2 + '\n')
                    f.write(ocrPy + '\n')

    # 识别线程显示
    def procShow(self, flist):
        print(flist)
        if len(flist) == 0:
            # 退出线程
            print('procThread exit')
            self.start = False
            self.procThread = None
        elif len(flist) == 1:
            # 当前处理数
            self.curOcrProcNums = flist[0]
        elif len(flist) == 4:
            # 写结果
            self.curOcrProcNums = flist[0]
            self.ocrProcNums += 1
            self.ocrProcJson(flist[1], flist[2], flist[3])
        # 刷新计数
        self.flushOcrNums()

    # 数据线程显示
    def dataShow(self, flist):
        print(flist)
        if len(flist) == 0:
            # 退出线程
            print('dataThread exit')
            self.start = False
            self.dataThread = None
        elif len(flist) == 3:
            # 著录图片
            self.lineEditFilmTitle.setText(flist[0])
            self.spinBoxFilmNo.setValue(flist[1])
            self.lineEditOcrProcFile.setText(flist[2])
            if self.curFilmTitle != flist[0] and self.curFilmNo != flist[1]:
                # 新著录项目
                self.curFilmTitle = flist[0]
                self.curFilmNo = flist[1]
                self.curOcrFilmNums = 0
            self.curOcrFilmNums += 1
            if self.OcrType == 1:
                ret = ocrJsonBaiduToResult(ocrProcBaidu(flist[2], None))
            else:
                ret = ocrJsonHanWangToResult(ocrProcHanWang(flist[2], None))
            print(ret)
            self.ocrProcJson(flist[0], flist[1], ret)
            self.uploadData(flist[2])
        # 刷新计数
        self.flushOcrNums()

    # 上传图片
    def uploadData(self, name):
        if self.isData and self.dataSsh != None:
            file = name[len(self.ocrPath) + 1:]
            byte = self.dataSsh.putFile(file)
            saveLog('upload [%s]-[%d]' % (file, byte), self.ocrPath, log='ocr.log')

    def flushTcpServer(self):
        self.spinBoxTcpPort.setReadOnly(self.isTcpServer == 0)
        if self.isTcpServer:
            if self.tcpServer == None:
                self.tcpStart()
        else:
            if self.tcpServer != None:
                self.tcpClose()

    def enableTcpServer(self, checked):
        self.isTcpServer = 1 if checked else 0
        self.config.writeConf('IsTcpServer', self.isTcpServer)
        self.flushTcpServer()

    def confTcpPort(self, value):
        self.tcpPort = value
        self.config.writeConf('TcpPort', self.tcpPort)

    def flushDatabase(self):
        self.lineEditDatabaseInterface.setReadOnly(self.isDb == 0)

    def enableDatabase(self, checked):
        self.isDb = 1 if checked else 0
        self.config.writeConf('IsDb', self.isDb)
        self.flushDatabase()

    def flushDataRemote(self):
        self.lineEditDataPath.setReadOnly(self.isData == 0)

    def enableDataRemote(self, checked):
        self.isData = 1 if checked else 0
        self.config.writeConf('IsData', self.isData)
        self.flushDataRemote()

    def wordSpaceChar(self, index):
        if index == self.comboBoxWordSpaceChar.currentIndex():
            self.ocrConfWordSpaceChar = self.comboBoxWordSpaceChar.currentText()
            self.config.writeConf('OcrConfWordSpaceChar', self.ocrConfWordSpaceChar)

    def delaySeconds(self, value):
        self.OcrConfPeriodTime = value
        self.config.writeConf('OcrConfPeriodTime', self.OcrConfPeriodTime)

    def upToDownWordNums(self, value):
        self.ocrConfUpToDownWordNums = value
        self.config.writeConf('OcrConfUpToDownWordNums', self.ocrConfUpToDownWordNums)

    def rightToLeft(self, checked):
        self.ocrConfRightToLeft = 1 if checked else 0
        self.config.writeConf('OcrConfRightToLeft', self.ocrConfRightToLeft)

    def upToDown(self, checked):
        self.ocrConfUpToDown = 1 if checked else 0
        self.config.writeConf('OcrConfUpToDown', self.ocrConfUpToDown)

    def fantiToJianti(self, checked):
        self.ocrConfFantiToJianti = 1 if checked else 0
        self.config.writeConf('OcrConfFantiToJianti', self.ocrConfFantiToJianti)

    # 选择处理目录
    def choiceOcrPath(self):
        path = QFileDialog.getExistingDirectory(self, " 选择图片处理目录 ", self.ocrPath)
        if os.path.exists(path):
            if path != self.ocrPath:
                self.ocrPath = path
                self.config.writeConf('OcrPath', path)
                self.lineEditScanDir.setText(self.ocrPath)


'''
mysql 写记录说明
    标题，卷号，目录文件名，文件名前缀，文件名扩展名，原始OCR，原始文本，简体文本，拼音文本
    filmTital，filmNo，pathFile，filenamePre，filenameExt，ocrJson，ocrTxt1，ocrTxt2，pyTxt
    
    archive_docset_microfilm            目录表
            *id              ---     auto        目录ID
            *name            ---     标题
            *volume_number   ---     卷号
            cat_id          ---     63
            folder_id       ---     2
            enterprise_id   ---     2
            public          ---     0
            doc_seq         ---     63
            project_id      ---     1
            *created_at      ---     now
            *updated_at      ---     now
            isimport        ---     1           
        
    archive_doc_microfilm               图片文件表
            *id              ---     auto        文件ID
            *docset_id       ---     目录id
            docset_id_relation_type --- 1
            project_id      ---         1
            folder_id       ---         2
            
            *original_file_name      --- 文件名前缀
            *original_file_extension --- 文件扩展名
            *storage_file_name       --- 文件名前缀
            *storage_file_extension  --- 文件扩展名
            *path_original           --- 目录文件名
            
            *size_original_kb        --- 文件K数
                        
    
            *created_at      ---     now
            *updated_at      ---     now
    
    archive_doc_microfilm_summary       图片识别表
            *id              ---     auto
            *doc_id          ---     文件ID 
            *docset_id       ---     目录ID
            
            *summary_json    ---     原始数据包
            *summary_old     ---     原始文本
            *summary_jianti  ---     简体文本
            *summary_pinyin  ---     拼音文本
            
            *created_at      ---     now
            *updated_at      ---     now

'''


# 处理识别线程
class ocrProcThread(QThread):
    update_item = pyqtSignal(list)

    def __init__(self, ocrPath, procName, ocrType, ocrPara):
        super().__init__()
        self.stop = False
        self.ocrPath = ocrPath
        self.name = procName
        self.ocrType = ocrType
        self.webHost = ''
        self.webPort = 0
        self.API_KEY = ''
        self.SECRET_KEY = ''
        self.maxByte = 0
        pl = ocrPara.split(',')
        if self.ocrType == 1:
            if len(pl) >= 2:
                self.API_KEY = pl[0]
                self.SECRET_KEY = pl[1]
        else:
            if len(pl) >= 2:
                self.webHost = pl[0]
                self.webPort = int(pl[1])
        if len(pl) > 2:
            self.maxByte = int(pl[2])

        self.procList = []
        self.readProc()

    # 读取未处理队列
    def readProc(self):
        if not os.path.exists(self.name):
            return
        with open(self.name, 'r', encoding='utf-8') as f:
            while True:
                line = f.readline()
                if not line:
                    break
                line = line.replace('\n', '')
                line = line.replace('\r', '')
                if len(line) == 0:
                    continue
                self.addProc(line)
            f.close()

    # 保存未处理队列
    def saveProc(self):
        with open(self.name, 'w', encoding='utf-8') as f:
            for proc in self.procList:
                f.write('%s\n' % (proc))
            f.close()
        self.procList.clear()

    # 停止
    def procStop(self):
        self.stop = True

    # 添加
    def addProc(self, data):
        d = eval(data)
        self.procList.append(d)
        print('proc nums : %d' % (len(self.procList)))
        # 添加新记录-1
        self.update_item.emit([len(self.procList)])

    # OCR处理百度
    def get_access_token(self):
        """
        使用 AK，SK 生成鉴权签名（Access Token）
        :return: access_token，或是None(如果错误)
        """
        url = "https://aip.baidubce.com/oauth/2.0/token"
        params = {"grant_type": "client_credentials", "client_id": self.API_KEY, "client_secret": self.SECRET_KEY}
        return str(requests.post(url, params=params).json().get("access_token"))

    def procDataBaidu(self, fileName):
        url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate?access_token=" + self.get_access_token()
        jname = fileName[:-4] + '.json'
        if os.path.isfile(jname):
            # 已经识别
            with open(jname, 'r', encoding="utf-8") as f:
                data = f.read()
                ocrJson = eval(json.loads(data))
        else:
            result = {}
            try:
                # 识别
                result = ocrBaiduName(url, fileName, self.maxByte)
                result['code'] = 0
            except Exception as e:
                result['code'] = 2
                ocrJson = None
            if result['code'] > 0:
                # 出错
                print('识别[%s] 错误：%s' % (fileName, getOcrState(result['code'])))
                saveLog('[%s]-[%s]' % (fileName, getOcrState(result['code'])), self.ocrPath, log='ocr.log')
            else:
                # 成功
                ocrJson = result
                print('识别[%s] 成功 [ID-%d,单词数-%d]' %
                      (fileName, result['log_id'], result['words_result_num']))
            f = open(jname, 'w', encoding="utf-8")
            f.write(json.dumps(str(ocrJson), ensure_ascii=False, indent=4, separators=(',', ':')))
            f.close()
        try:
            ocrDict = ocrProcBaidu(fileName, ocrJson)
            ret = ocrJsonBaiduToResult(ocrDict)
        except Exception as e:
            saveLog('[%s]-[%s]' % (fileName, str(e)), self.ocrPath, log='ocr.log')
            ret = None
        return ret

    # OCR处理汉王
    def procDataHanWang(self, fileName):
        url = 'http://%s:%d' % (self.webHost, self.webPort)
        jname = fileName[:-4] + '.json'
        if os.path.isfile(jname):
            # 已经识别
            with open(jname, 'r', encoding="utf-8") as f:
                data = f.read()
                ocrJson = eval(json.loads(data))
        else:
            result = {}
            try:
                result = ocrHanWangName(url, fileName)
            except Exception as e:
                result['code'] = 999
                result['result'] = '{}'
                ocrJson = None
            if result['code'] > 0:
                # 出错
                print('识别[%s] 错误：%s' % (fileName, getOcrState(result['code'])))
                saveLog('[%s]-[%s]' % (fileName, getOcrState(result['code'])), self.ocrPath, log='ocr.log')
            else:
                # 成功
                ocrJson = result['result']
                print('识别[%s] 成功 [宽度-%d,高度-%d,元素数-%d]' %
                      (fileName, result['Width'], result['Height'], result['Layouts_num']))
            f = open(jname, 'w', encoding="utf-8")
            f.write(json.dumps(str(ocrJson), ensure_ascii=False, indent=4, separators=(',', ':')))
            f.close()
        try:
            ocrDict = ocrProcHanWang(fileName, ocrJson)
            ret = ocrJsonHanWangToResult(ocrDict)
        except Exception as e:
            saveLog('[%s]-[%s]' % (fileName, str(e)), self.ocrPath, log='ocr.log')
            ret = None
        return ret

    # 运行
    def run(self):
        while True:
            if self.stop:
                break
            time.sleep(0.5)
            if len(self.procList) == 0:
                continue
            # 处理信息-3
            data = self.procList.pop(0)
            if self.ocrType == 1:
                ret = self.procDataBaidu(data['Image'])
            else:
                ret = self.procDataHanWang(data['Image'])
            self.update_item.emit([len(self.procList), data['FilmTitle'], data['FilmNo'], ret])
        # 退出
        self.saveProc()
        self.update_item.emit([])


# 处理数据线程
class ocrDataThread(QThread):
    update_item = pyqtSignal(list)

    def __init__(self, dataName):
        super().__init__()
        self.stop = False
        self.name = dataName
        self.dataList = []
        self.readData()

    # 读取未处理队列
    def readData(self):
        if not os.path.exists(self.name):
            return
        with open(self.name, 'r', encoding='utf-8') as f:
            while True:
                line = f.readline()
                if not line:
                    break
                line = line.replace('\n', '')
                line = line.replace('\r', '')
                if len(line) == 0:
                    continue
                self.addData(line)
            f.close()

    # 保存未处理队列
    def saveData(self):
        with open(self.name, 'w', encoding='utf-8') as f:
            for data in self.dataList:
                f.write('%s\n' % (data))
            f.close()
        self.dataList.clear()

    # 停止
    def dataStop(self):
        self.stop = True

    # 添加
    def addData(self, data):
        d = eval(data)
        self.dataList.append(d)
        print(self.dataList)

    # 运行
    def run(self):
        while True:
            if self.stop:
                break
            time.sleep(0.5)
            if len(self.dataList) == 0:
                continue
            # 处理信息-3
            data = self.dataList.pop(0)
            self.update_item.emit([data['FilmTitle'], data['FilmNo'], data['Image']])
        # 退出
        self.saveData()
        self.update_item.emit([])


if __name__ == '__main__':
    # print('图片识别')
    getPinYin()
    getFanTi()

    # 写数据
    app = QApplication(sys.argv)

    main = ocrRun()
    main.show()

    sys.exit(app.exec_())
